package kpi.java_training.web;

import kpi.java_training.domain.Model;
import kpi.java_training.domain.questions.QuestionData;
import kpi.java_training.domain.teaching.TeachingSystem;
import kpi.java_training.users.UserManager;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@Controller
public class FirstController {
    Model subSystem;
    String userName;

    //
    // TODO: string constants for .jsp files
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(HttpServletRequest request) {
        request.setAttribute("message", "");
        return "index";
    }

    @RequestMapping(value = "/login/", method = RequestMethod.POST)
    public String performAuthentication(HttpServletRequest request, HttpSession session, String userName, String password) {
        UserManager userManager = new UserManager();
        if (!userManager.userExists(userName)) {
            request.setAttribute("message", "User not found! Please enter correct user name.");
            return "index";
        }
        if (userManager.isPasswordCorrect(userName, password)) {
            performLogin(session, userManager.getOriginalUserName(userName));
            return "main";
        }
        request.setAttribute("message", "Wrong password! Please try again.");
        return "index";
    }

    private void performLogin(HttpSession session, String userName) {
        this.userName = userName;
        session.setAttribute("userName", this.userName);
    }

    @RequestMapping(value = "/registration/", method = RequestMethod.GET)
    public String performRegistration() {
        return "registration";
    }

    @RequestMapping(value = "/register/", method = RequestMethod.POST)
    public String performRegistration(HttpServletRequest request, HttpSession session, String userName, String password) {
        if ((userName == null) || (password == null)) {
            request.setAttribute("message", "User name or password cannot be empty.");
            return "registration";
        }
        UserManager userManager = new UserManager();
        if (userManager.userExists(userName)) {
            request.setAttribute("message", "User already exists! Please try different name.");
            return "registration";
        }
        userManager.appendUser(userName, password);
        performLogin(session, userName);
        return "main";
    }

    // TODO: refactor
    @RequestMapping(value = "/start_learning/", method = RequestMethod.GET)
    public String startLearning(HttpServletRequest request) {
        if (subSystem == null) {
            request.setAttribute("message", "You need to log in first!");
            return "index";
        }
        subSystem.startNewSession();
        nextTeachingStep(request);
        return "learning_step";
    }

    @RequestMapping(value = "/continue_learning/", method = RequestMethod.GET)
    public String continueLearning(HttpServletRequest request) {
        if (subSystem == null) {
            request.setAttribute("message", "You need to log in first!");
            return "index";
        }
        subSystem.continueSavedSession();
        nextTeachingStep(request);
        return "learning_step";
    }

    @RequestMapping(value = "/next_question/", method = RequestMethod.POST)
    public String nextLearningStep(HttpServletRequest request) {
        String answer = getResultAnswer(request);
        subSystem.processAnswer(answer);
        processResult(request);
        if (subSystem.workComplete()) {
            return "result";
        }
        nextTeachingStep(request);
        return "learning_step";
    }

    @RequestMapping(value = "/undo/", method = RequestMethod.GET)
    public String performUndo(HttpServletRequest request) {
        subSystem.executeUndo();
        nextTeachingStep(request);
        return "learning_step";
    }

    @RequestMapping(value = "/break/", method = RequestMethod.GET)
    public String performBreak(HttpServletRequest request) {
        subSystem.executeBreak();
        request.setAttribute("userName", userName);
        return "main";
    }

    @RequestMapping(value = "/logout/", method = RequestMethod.GET)
    public String performLogout(HttpServletRequest request) {
        userName = "";
        subSystem = null;
        return "index";
    }

    @RequestMapping(value = "/main/", method = RequestMethod.GET)
    public String getMain() {
        return "main";
    }

    @RequestMapping(value = "/learning_mode/", method = RequestMethod.GET)
    public String learningMode(HttpSession session) {
        subSystem = new TeachingSystem(userName);
        session.setAttribute("systemMode", "Learning Mode");
        return "learning";
    }

    @RequestMapping(value = "/testing_mode/", method = RequestMethod.GET)
    public String testingMode() {
        return "testing";
    }

    private void nextTeachingStep(HttpServletRequest request) {
        subSystem.setNextStep();
        QuestionData questionData = subSystem.getCurrentQuestionData();
        request.setAttribute("questionData", questionData);
    }

    private void processResult(HttpServletRequest request) {
        if (subSystem.getResult()) {
            request.setAttribute("questionResult", "Answer is correct!");
        } else {
            request.setAttribute("questionResult", "Answer is wrong!");
        }
    }

    private String getResultAnswer(HttpServletRequest request) {
        String [] answers = request.getParameterValues("answer");
        if ((answers == null) || (answers.length == 0)) {
            return "";
        }
        String resultAnswer = answers[0];
        for (int i = 1; i < answers.length; i++) {
            resultAnswer = String.format("%s,%s", resultAnswer, answers[i]);
        }
        return resultAnswer;
    }
}
